package com.shanpin.shebao.web.module.game;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.shanpin.core.constant.EnvConf;
import com.shanpin.core.http.MJsonView;
import com.shanpin.core.utils.DateUtil;
import com.shanpin.core.utils.JodaUtil;
import com.shanpin.core.utils.JsonUtil;
import com.shanpin.shebao.model.ServiceResult;
import com.shanpin.shebao.web.module.game.model.AwardConfig;
import com.shanpin.shebao.web.module.game.model.EStatisEvent;
import com.shanpin.shebao.web.module.game.model.EStatus;
import com.shanpin.shebao.web.module.game.model.GameConfig;
import com.shanpin.shebao.web.module.game.util.RegexUtil;
import com.shanpin.shebao.web.module.game.util.SessionUtil;
import com.shanpin.shebao.web.module.game.vo.GameAwardListVO;
import com.shanpin.shebao.web.module.game.vo.GameRecomPointVO;
import com.shanpin.shebao.web.module.game.vo.GameUserBaseVO;
import com.shanpin.shebao.web.module.game.vo.GameUserGiftVO;
import com.shanpin.shebao.web.module.game.vo.GameUserVO;
import com.shanpin.shebao.web.service.WXOAuthService;
import com.shanpin.shebao.web.service.WXOAuthService.WXUserinfo;

@Controller
@RequestMapping("/game")
public class GameController{

	@Autowired
	private GameService gameService;
	@Autowired
	private GameStatisService gameStatisService;
	@Autowired
	private WXOAuthService wXOAuthService;
	
	@RequestMapping(path="/index", method=RequestMethod.GET)
	public ModelAndView index(HttpServletRequest request,
			String code, String state, String recom) {
		ModelAndView mv = new ModelAndView("yearend/index");
		if(EnvConf.isProd()) {
			if(StringUtil.isBlank(code)) {
				String redirectUrl = "http://192.168.1.99/sbw/game/index";
				if(StringUtil.isBlank(recom)) {
					recom = "STATE";
				}
				String url = WXOAuthService.getOauth2Url(redirectUrl, WXOAuthService.SCOPE_SNSAPI_USERINFO, recom);
				mv.setViewName("redirect:"+url);
				return mv;
			}
		}
		String openid = null;
		String nickname = null;
		String headimg = null;
		int userId = 0;
		int recomUserId = 0;
		String recomOpenid = "";
		if(EnvConf.isProd()) {
			WXUserinfo userinfo = wXOAuthService.getUserinfo(code);
			 if(userinfo == null) {
				 return null;
			 }
			 openid = userinfo.getOpenid();
			 nickname = userinfo.getNickname();
			 if(nickname == null) {
				 nickname = "";
			 }
			 //过滤特殊字符
			 StringBuffer buffer = new StringBuffer(32);
			 char[] chars = nickname.toCharArray(); 
			 for(int i = 0; i<chars.length; i ++) { 
				 if((chars[i] >= 19968 && chars[i] <= 40869) 
						 || (chars[i] >= 97 && chars[i] <= 122) 
						 || (chars[i] >= 65 && chars[i] <= 90)) { 
					 buffer.append(chars[i]);
				 } 
			 }
			 nickname = buffer.toString();
			 if(nickname.length()>32) {
				 nickname = nickname.substring(0, 32);
			 }
			 headimg = userinfo.getHeadimgurl();
		} else {
			openid = request.getParameter("openid");
			nickname = request.getParameter("nickname");
			headimg = request.getParameter("headimg");
			state = request.getParameter("state");
		}
		
		boolean newUser = false;
		GameUserVO user = gameService.getUser(openid);
		if(user == null) {
			userId = gameService.addUser(openid, nickname, headimg);
			newUser = true;
		} else {
			userId = user.getUserId();
		}
		//获取推荐链接信息
		if(StringUtil.isNotBlank(state) && !"STATE".equals(state)) {
			recomOpenid = state;
			GameUserVO recomUser = gameService.getUser(recomOpenid);
			if(recomUser != null) {
				recomUserId = recomUser.getUserId();
				if(recomUserId != userId) {
					//推荐关系不存在的话，新建推荐信息
					if(!gameService.existRecom(userId, recomUserId)) {
						gameService.addRecom(userId, recomUserId);
					}
				} else {
					recomUserId = 0;
				}
			}
		}
		
		SessionUtil.putUid(request, userId);
		SessionUtil.putRecomUid(request, recomUserId);
		
		boolean fromShare = recomUserId>0;
		//PV统计
		if(fromShare) {
			gameStatisService.incStatisEventToCache(EStatisEvent.PV, DateUtil.yyyy_MM_dd()+"_SHARE");
		} else {
			gameStatisService.incStatisEventToCache(EStatisEvent.PV, DateUtil.yyyy_MM_dd()+"_SELF");
		}
		//UV统计
		long lastVisitTime = gameService.getVisitTimeOfCache(userId);
		long curTime = System.currentTimeMillis();
		if(lastVisitTime==0 || JodaUtil.daysCompare(new Date(lastVisitTime), new Date(curTime))>0) {
			if(fromShare) {
				gameStatisService.incStatisEventToCache(EStatisEvent.UV, DateUtil.yyyy_MM_dd()+"_SHARE");
			} else {
				gameStatisService.incStatisEventToCache(EStatisEvent.UV, DateUtil.yyyy_MM_dd()+"_SELF");
			}
		}
		gameService.updateVisitTimeOfCache(userId);
		//游戏用户统计
		if(newUser) {
			if(fromShare) {
				gameStatisService.incStatisEventToCache(EStatisEvent.U, DateUtil.yyyy_MM_dd()+"_SHARE");
			} else {
				gameStatisService.incStatisEventToCache(EStatisEvent.U, DateUtil.yyyy_MM_dd()+"_SELF");
			}
		}
		
		mv.addObject("config", JsonUtil.toStr(GameConfig.gameConfig()));
		mv.addObject("url", "http://192.168.1.99/sbw/game/index?recom="+openid);
		return mv;
	}
	
	@RequestMapping(path="/winning", method=RequestMethod.GET)
	public ModelAndView winning() {
		ModelAndView mv = new ModelAndView("yearend/winning");
		List<GameAwardListVO> awardList_2017122820 = gameService.listAwardList(GameConfig._2017122820);
		mv.addObject("awardList_2017122820", awardList_2017122820);
		
		List<GameAwardListVO> awardList_2017122912 = gameService.listAwardList(GameConfig._2017122912);
		mv.addObject("awardList_2017122912", awardList_2017122912);
		
		List<GameAwardListVO> awardList_2017122920 = gameService.listAwardList(GameConfig._2017122920);
		mv.addObject("awardList_2017122920", awardList_2017122920);
		
		List<GameAwardListVO> awardList_2017123012 = gameService.listAwardList(GameConfig._2017123012);
		mv.addObject("awardList_2017123012", awardList_2017123012);
		
		List<GameAwardListVO> awardList_2017123020 = gameService.listAwardList(GameConfig._2017123020);
		mv.addObject("awardList_2017123020", awardList_2017123020);
		
		List<GameAwardListVO> awardList_2017123021 = gameService.listAwardList(GameConfig._2017123021);
		mv.addObject("awardList_2017123021", awardList_2017123021);
		return mv;
	}
	
	@RequestMapping(path="/test", method=RequestMethod.GET)
	public ModelAndView test(int batch, String r) {
		if(EnvConf.isProd()) {
			return MJsonView.fail("生产环境不能调用");
		}
		if(batch>0) {
			if("y".equals(r)) {
				int size = gameService.size();
				Random random = new Random(System.currentTimeMillis()-size);
				List<AwardConfig> awardConfigList = new ArrayList<>(100);
				Set<Integer> set = new HashSet<>();
				int c = 0;
				int curTry = 0;
				while(c<100 && curTry<500) {
					int rank = 1+random.nextInt(size);
					if(set.add(rank)) {
						AwardConfig awardConfig = new AwardConfig();
						awardConfig.setAward(500);
						awardConfig.setRank(rank);
						awardConfigList.add(awardConfig);
						c++;
					}
					curTry++;
				}
				gameService.genAwardList(batch, awardConfigList);
			} else {
				List<AwardConfig> awardConfigList = GameConfig.gameConfig().getAwardList();
				gameService.genAwardList(batch, awardConfigList);
			}
		}
		return MJsonView.ok();
	}
		
	//游戏用户详细信息
	@RequestMapping(path="/user", method=RequestMethod.GET)
	public ModelAndView user(HttpServletRequest request) {
		int userId = SessionUtil.getUid(request);
		int recomUserId = SessionUtil.getRecomUid(request);
		GameUserVO user = gameService.getUser(userId);
		if(user.getAward()>0 & EStatus.of(user.getAwardStatus()) == EStatus.NO_RECEIVE) {
			gameService.notifyAward(userId);
		}
		if(recomUserId>0) { //游戏状态更新从朋友关系那里获取
			GameRecomPointVO recomPoint = gameService.getRecomPoint(userId, recomUserId);
			if(recomPoint != null) {
				user.setGiftPlay(recomPoint.getGiftPlay());
			}
		}
		int nDays = GameConfig.nDays();
		user.setnDays(nDays);
		user.setRecomUserId(recomUserId);
		return MJsonView.ok(user);
	}

	//用户礼物值、排名动态信息
	@RequestMapping(path="/user/dynamic", method=RequestMethod.GET)
	public ModelAndView userDynamic(HttpServletRequest request) {
		int userId = SessionUtil.getUid(request);
		GameUserBaseVO user = gameService.getUserDynamic(userId);
		return MJsonView.ok(user);
	}
	
	//Top50排名
	@RequestMapping(path="/rank", method=RequestMethod.GET)
	public ModelAndView rank(HttpServletRequest request) {
		List<GameUserBaseVO> userList = gameService.listTopRank();
		return MJsonView.ok(userList);
	}
	
	//用户排名
	@RequestMapping(path="/user/rank", method=RequestMethod.GET)
	public ModelAndView userRank(HttpServletRequest request) {
		int userId = SessionUtil.getUid(request);
		List<GameUserBaseVO> userList = gameService.listUserRank(userId);
		return MJsonView.ok(userList);
	}
	
	//用户好友助力值
	@RequestMapping(path="/user/recom", method=RequestMethod.GET)
	public ModelAndView userRecom(HttpServletRequest request) {
		int recomUserId =SessionUtil.getUid(request);
		List<GameRecomPointVO> recomPointList = gameService.listRecomPoint(recomUserId);
		return MJsonView.ok(recomPointList);
	}
	
	//用户戳礼物
	@RequestMapping(path="/user/gift/{giftId}", method=RequestMethod.POST)
	public ModelAndView userGift(HttpServletRequest request, @PathVariable("giftId")int giftId) {
		GameConfig config = GameConfig.gameConfig();
		long curTime = System.currentTimeMillis();
		/*if(curTime<config.getBeginTime()) {
			return MJsonView.fail("游戏还没开始~");
		}*/
		if(curTime>config.getEndTime()) {
			return MJsonView.fail("游戏已结束~");
		}
		int userId =SessionUtil.getUid(request);
		if(giftId<1 || giftId>3) {
			return MJsonView.fail("礼物编号不在允许范围");
		}
		int nDays = GameConfig.nDays();
		int recomUserId = SessionUtil.getRecomUid(request);
		ServiceResult<Integer> sr = gameService.updateIncPoint(userId, recomUserId, nDays, giftId);
		if(StringUtil.isNotBlank(sr.msg)) {
			return MJsonView.fail(sr.msg);
		}
		Map<String, String> ret = new HashMap<>();
		//所有的礼物都拆了，则返回信息
		boolean allGiftPlayed = true;
		if(recomUserId == 0) {
			GameUserVO user = gameService.getUser(userId);
			int giftPlay = user.getGiftPlay();
			for(int i=1; i<=3; i++) {
				int mask =1<<((i-1)+(nDays*3));
				int play = giftPlay&mask;
				if(play == 0) {
					allGiftPlayed = false;
				}
			}
			if(allGiftPlayed) {
				String pointDetail = user.getPointDetail();
				if(StringUtil.isNotBlank(pointDetail)) {
					 Map<String, GameUserGiftVO> map = JsonUtil.string2Map(pointDetail, String.class, GameUserGiftVO.class);
					 int incPoint = 0;
					 int incRank = 0;
					 for(int i=1; i<=3; i++) {
						 GameUserGiftVO ug = map.get(nDays+"_"+i);
						 if(ug != null) {
							 incPoint += ug.getP();
							 incRank += ug.getR();
						 }
					 }
					 ret.put("type", "self");
					 ret.put("point", String.valueOf(sr.result));
					 ret.put("recomUserId", String.valueOf(recomUserId));
					 ret.put("recomNickname", "");
					 ret.put("incPoint", String.valueOf(incPoint));
					 ret.put("incRank", String.valueOf(incRank));
					 return MJsonView.ok(ret);
				}
			}
		} else {
			GameRecomPointVO recomPoint =  gameService.getRecomPoint(userId, recomUserId);
			int giftPlay = recomPoint.getGiftPlay();
			for(int i=1; i<=3; i++) {
				int mask =1<<((i-1)+(nDays*3));
				int play = giftPlay&mask;
				if(play == 0) {
					allGiftPlayed = false;
				}
			}
			if(allGiftPlayed) {
				String pointDetail = recomPoint.getPointDetail();
				if(StringUtil.isNotBlank(pointDetail)) {
					 Map<String, GameUserGiftVO> map = JsonUtil.string2Map(pointDetail, String.class, GameUserGiftVO.class);
					 int incPoint = 0;
					 int incRank = 0;
					 for(int i=1; i<=3; i++) {
						 GameUserGiftVO ug = map.get(nDays+"_"+i);
						 if(ug != null) {
							 incPoint += ug.getP();
							 incRank += ug.getR();
						 }
					 }
					 GameUserBaseVO recomU = gameService.getUserDynamic(recomUserId);
					 ret.put("type", "recom");
					 ret.put("point", String.valueOf(sr.result));
					 ret.put("recomUserId", String.valueOf(recomUserId));
					 ret.put("recomNickname", recomU.getNickname());
					 ret.put("incPoint", String.valueOf(incPoint));
					 ret.put("incRank", String.valueOf(incRank));
					 return MJsonView.ok(ret);
				}
			}
		}
		ret.put("type", "one");
		ret.put("point", String.valueOf(sr.result));
		return MJsonView.ok(ret);
	}
	
	//用户领奖和优惠券
	@RequestMapping(path="/user/receive", method=RequestMethod.POST)
	public ModelAndView receive(HttpServletRequest request, 
			String phone, int cStatus, int aStatus) {
		GameConfig config = GameConfig.gameConfig();
		long curTime = System.currentTimeMillis();
		if(curTime>config.getReceiveTime()) {
			return MJsonView.fail("过了领奖时间了~");
		}
		int userId =SessionUtil.getUid(request);
		if(StringUtil.isBlank(phone)) {
			return MJsonView.fail("手机号码为空");
		}
		if(!RegexUtil.isPhone(phone)) {
			return MJsonView.fail("手机号码格式不正确");
		}
		EStatus couponStatus = EStatus.of(cStatus);
		if(couponStatus == null) {
			return MJsonView.fail("优惠券领取状态未定义");
		}
		EStatus awardStatus = EStatus.of(aStatus);
		if(awardStatus == null) {
			return MJsonView.fail("话费券领取状态未定义");
		}
		if(couponStatus != EStatus.RECEIVE && awardStatus != EStatus.RECEIVE) {
			return MJsonView.fail("优惠券和话费券状态均是未领取");
		}
		GameUserVO user = gameService.getUser(userId);
		if(user.getPhone()!=null && !user.getPhone().equals(phone)) {
			return MJsonView.fail("号码不一致");
		}
		if(couponStatus == EStatus.RECEIVE) {
			if(user.getCoupon()>0 && EStatus.of(user.getCouponStatus()) != EStatus.RECEIVE) {
				gameService.receiveCoupon(userId, phone);
			}
		}
		if(awardStatus == EStatus.RECEIVE) {
			if(user.getAward()>0 && EStatus.of(user.getAwardStatus()) != EStatus.RECEIVE) {
				gameService.receiveAward(userId, phone);
			}
		}
		return MJsonView.ok();
	}
}
